﻿using System;

namespace IupNET
{
    public enum ClientImageType
    {
        Map,
        RGB,
        RGBA
    }

    public class ClientImage:IDisposable
    {
        public readonly int Width;
        public readonly int Height;
        public readonly ClientImageType Type;

        /// <summary>
        /// Array of red components for the image. Valid if Type is RGB or RGBA.
        /// </summary>
        public readonly byte[] Red;

        /// <summary>
        /// Array of green components for the image. Valid if Type is RGB or RGBA.
        /// </summary>
        public readonly byte[] Green;

        /// <summary>
        /// Array of blue components for the image. Valid if Type is RGB or RGBA.
        /// </summary>
        public readonly byte[] Blue;

        /// <summary>
        /// Array of alpha components for the image. Valid if Type is RGBA.
        /// </summary>
        public readonly byte[] Alpha;

        /// <summary>
        /// Index map of image. Valid if Type is 'Map'.
        /// </summary>
        public readonly byte[] Map;

        /// <summary>
        /// Color palette of image. Valid if type is 'Map'
        /// </summary>
        public readonly int[] Colors=new int[256];   //used for map


        /// <summary>
        /// Creates a client image with the given type.
        /// </summary>
        public ClientImage(int w, int h, ClientImageType type)
        {
            Type = type;
            Width = w;
            Height = h;

            int n=w*h;

            if (type == ClientImageType.Map)
            {
                Map = new byte[w * h];
                for (int l = 0; l < 256; l++) //create grayscale map
                    Colors[l] = Cdc.EncodeColor((byte)l, (byte)l, (byte)l);
            }
            else if(type==ClientImageType.RGB || type==ClientImageType.RGBA) {
                Red = new byte[w * h];
                Green = new byte[w * h];
                Blue = new byte[w * h];
            }

            if (type == ClientImageType.RGBA)
            {
                Alpha = new byte[w * h];
                
            }
        }

       

        internal ClientImage(int w, int h, byte[] r, byte[] g, byte[] b, byte[] a, byte[] map)
        {
            Red = r;
            Green = g;
            Blue = b;
            Alpha = a;
            Map = map;
            Width = w;
            Height = h;

            //calc. type of image
            if (r != null)
            {
                if (a != null)
                    Type = ClientImageType.RGBA;
                else
                    Type = ClientImageType.RGB;
            }
            else if (map != null)
            {
                Type = ClientImageType.Map;
                for (int l = 0; l < 256; l++) //create grayscale map
                    Colors[l] = Cdc.EncodeColor((byte)l, (byte)l, (byte)l);
            }
            else
                throw new ArgumentException("Errnous parameters to client image constructor");
        }


        /// <summary>
        /// Copies a rectangle from a canvas to the client image. The image has to be a RGB image or an exception is thrown.
        /// </summary>
        public void Copy(Canvas c, int x, int y)
        {

            if (Type != ClientImageType.RGB)
                throw new Exception("ClientImage has to be of type ClientImageType.RGB to use Copy function");


            Cdc.CanvasGetImageRGB(c.cobj, Red, Green, Blue, x, y, Width, Height);


        }

        /// <summary>
        /// Compute a 256 color indexed version of this image.
        /// The color array for the new image are computed automagically.
        /// </summary>
        /// <returns></returns>
        public ClientImage ConvertToMap()
        {
            if (Type == ClientImageType.Map)
                return this;    //done already
            byte[] map=new byte[Width*Height];
            int[] colors=new int[256];
            Cdc.RGB2Map(Width, Height, ref Red[0], ref Green[0], ref Blue[0], map, 256, colors);
            ClientImage res=new ClientImage(Width, Height, null, null, null, null, map);
            Array.Copy(colors, res.Colors, 256);
            return res;
        }


        public void Dispose()
        {
           //no need to dispose anything here, just to be easy to swap between server and client images in code....
        }

    }
}
